package com.RunAndHappy.q779178.utils;

import com.aizuda.common.toolkit.CollectionUtils;
import com.aizuda.monitor.DiskInfo;
import com.aizuda.monitor.OshiMonitor;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import oshi.SystemInfo;
import oshi.software.os.OSProcess;
import oshi.software.os.OperatingSystem;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Configuration
public class OSHIMonitorUtil {

    @Autowired(required = false)
    private OshiMonitor oshiMonitor=new OshiMonitor(new SystemInfo());

    @SneakyThrows
    public void appendAllDiskUsePercent(String infoType, Map<String, Object> OSHIInfoMap) {

        // 磁盘信息
        List<DiskInfo> diskInfoList = this.oshiMonitor.getDiskInfos();

        if (CollectionUtils.isNotEmpty(diskInfoList)) {

            long usableSpace = 0;
            long totalSpace = 0;

            for (DiskInfo diskInfo : diskInfoList) {

                usableSpace += diskInfo.getUsableSpace();
                totalSpace += diskInfo.getTotalSpace();

            }

            double usedSize = (totalSpace - usableSpace);

            OSHIInfoMap.put(infoType, this.oshiMonitor.formatDouble((usedSize / totalSpace) * 100));

        }

    }

    @SneakyThrows
    public void appendProcessList(Integer limitNumber, String infoType, Map<String, Object> OSHIInfoMap) {

        // 系统前 10 个进程
        List<OSProcess> processList = this.oshiMonitor.getOperatingSystem().getProcesses(
                null, OperatingSystem.ProcessSorting.CPU_DESC, limitNumber
        );

        List<Map<String, Object>> processMapList = new ArrayList<>();

        for (OSProcess process : processList) {

            Map<String, Object> processMap = new HashMap<>(5);

            processMap.put("name", process.getName());
            processMap.put("pid", process.getProcessID());
            processMap.put("cpu", this.oshiMonitor.formatDouble(process.getProcessCpuLoadCumulative()));

            processMapList.add(processMap);

        }

        OSHIInfoMap.put(infoType, processMapList);

    }

    @SneakyThrows
    public void appendHardwareAbstractionLayer(String infoType, Map<String, Object> OSHIInfoMap) {

        Map<String, Object> hardwareAbstractionLayerMap = new HashMap<>();

        hardwareAbstractionLayerMap.put("memory", this.oshiMonitor.getHardwareAbstractionLayer().getMemory());
        hardwareAbstractionLayerMap.put("sensors", this.oshiMonitor.getHardwareAbstractionLayer().getSensors());
        hardwareAbstractionLayerMap.put("soundCards", this.oshiMonitor.getHardwareAbstractionLayer().getSoundCards());
        hardwareAbstractionLayerMap.put("diskStores", this.oshiMonitor.getHardwareAbstractionLayer().getDiskStores());
        hardwareAbstractionLayerMap.put("powerSources", this.oshiMonitor.getHardwareAbstractionLayer().getPowerSources());
        hardwareAbstractionLayerMap.put("networkIFs", this.oshiMonitor.getHardwareAbstractionLayer().getNetworkIFs());
        hardwareAbstractionLayerMap.put("graphicsCards",this.oshiMonitor.getHardwareAbstractionLayer().getGraphicsCards());
        hardwareAbstractionLayerMap.put("logicalVolumeGroups",this.oshiMonitor.getHardwareAbstractionLayer().getLogicalVolumeGroups());

        OSHIInfoMap.put(infoType, hardwareAbstractionLayerMap);

    }

    @SneakyThrows
    public void appendDataInOSHIInfoMap(String infoType, Map<String, Object> OSHIInfoMap) {

        switch (infoType) {

            // 系统信息
            case "sysInfo":

                OSHIInfoMap.put(infoType, this.oshiMonitor.getSysInfo());

                break;

            // CPU 信息
            case "cpuInfo":

                OSHIInfoMap.put(infoType, this.oshiMonitor.getCpuInfo());

                break;

            // 磁盘信息
            case "diskInfoList":

                OSHIInfoMap.put(infoType, this.oshiMonitor.getDiskInfos());

                break;

            // JVM 虚拟机信息
            case "jvmInfo":

                OSHIInfoMap.put(infoType, this.oshiMonitor.getJvmInfo());

                break;

            // 内存信息
            case "memoryInfo":

                OSHIInfoMap.put(infoType, this.oshiMonitor.getMemoryInfo());

                break;

            // 网络带宽信息
            case "netBandwidthInfo":

                OSHIInfoMap.put(infoType, this.oshiMonitor.getNetIoInfo());

                break;

            // 所有磁盘的使用率信息
            case "allDiskUsePercent":

                this.appendAllDiskUsePercent(infoType, OSHIInfoMap);

                break;

            // 系统前10个进程信息
            case "processList":

                this.appendProcessList(10, infoType, OSHIInfoMap);

                break;

            // 计算机系统信息
            case "computerSystem":

                OSHIInfoMap.put(infoType, this.oshiMonitor.getComputerSystem());

                break;

            // 中央处理器信息
            case "centralProcessor":

                OSHIInfoMap.put(infoType, this.oshiMonitor.getCentralProcessor());

                break;

            // 硬件抽象层信息
            case "hardwareAbstractionLayer":

                this.appendHardwareAbstractionLayer(infoType, OSHIInfoMap);

                break;

            // 系统属性信息
            case "systemProperties":

                OSHIInfoMap.put(infoType, this.oshiMonitor.getSystemProperties());

                break;

        }

    }

    @SneakyThrows

    // get oshi info function
    public Map<String, Object> GetOSHIInfo(List<String> infoTypeList) {

        Map<String, Object> OSHIInfoMap = new HashMap<>(5);

        for (String infoType: infoTypeList) {

            this.appendDataInOSHIInfoMap(infoType, OSHIInfoMap);

        }

        return OSHIInfoMap;

    }

}
